package com.ldy.seal.web;

import java.io.ByteArrayInputStream;
import java.math.BigInteger;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ldy.seal.entity.UserCert;
import com.ldy.seal.service.UserCertService;
import com.ldy.seal.util.CertManager;
import com.nja.util.encoders.Base64;
/**
 * 制作用户证书
 * @author lindeyi
 *
 */
@RestController
@RequestMapping("/cert")
@CrossOrigin(allowCredentials = "true", allowedHeaders = "*")
public class MakeCertController {

	Logger logger = LoggerFactory.getLogger(MakeCertController.class);

	@Autowired
	private UserCertService userCertService;
	
	/**
	 * 测试
	 * @param request
	 * @return String
	 */
	@GetMapping("/hi")
	public String hi(HttpServletRequest request) {
		// 签名
		return "SUCCESS";
	}
	
	/**
	 * 获取证书内容信息
	 * @param cert
	 * @return Result
	 */
	@PostMapping("/info")
	public Result info(String cert) {
		try {
			ByteArrayInputStream bio = new ByteArrayInputStream(Base64.decode(cert));
			CertificateFactory cf = CertificateFactory.getInstance("X.509");
			X509Certificate certificate = (X509Certificate) cf.generateCertificate(bio);
			BigInteger serialNumber = certificate.getSerialNumber();
			String issuer = certificate.getIssuerDN().getName();
			String subject = certificate.getSubjectDN().getName();
			return Result.success().map("serialNumber", serialNumber.toString(16)).map("issuer", issuer).map("subject", subject);
		} catch (Exception e) {
			return Result.failure(e.getMessage());
		}
		
	}
	
	
	/**
	 * 制作用户证书
	 * @param p10data
	 * @param userId
	 * @param userName
	 * @return Result
	 */
	@PostMapping("/makeUserCert")
	public Result makeUserCert(String p10data, String userId, String userName) {
		try {
			logger.info("method: {}, params:[p10data: {}, userId: {}, userName: {}]", "makeUserCert", p10data, userId, userName);
			// TODO 用户证书记录保存表中
			String userCert = Base64.toBase64String(CertManager.getIns().makeUserCert(p10data, userId));
			UserCert cert = new UserCert();
			cert.setUserId(userId);
			cert.setUserName(userName);
			userCertService.saveOrUpdate(cert);
			String caCert = Base64.toBase64String(CertManager.getIns().getCACert());
			String rootCert = Base64.toBase64String(CertManager.getIns().getRootCert());
			return Result.success().map("userCert", userCert).map("caCert", caCert).map("rootCert", rootCert);
		} catch (Exception e) {
			return Result.failure(e.getMessage());
		}
	}
	
	
	@PostMapping("/selectPage")
	public Result selectPage(int current, int size, String searchText) {
		Page<UserCert> page = userCertService.selectPage(current, size, searchText);
		return Result.success(page);
	}
	
	/**
	 * 判断用户序列号是否存在
	 * 
	 * @param userId
	 * @return
	 */
	@PostMapping("/exists")
	public Result exists(String userId) {
		UserCert cert = userCertService.selectByUserId(userId);
		if (null == cert) {
			return Result.success(true);
		}
		return Result.success(false);
	}

	/**
	 * 当前ca证书信息
	 * @param cert
	 * @return Result
	 */
	@PostMapping("/ca")
	public Result ca() {
		try {
			Map<String, Object> ca = toCert(CertManager.getIns().getCACert());
			return Result.success().map("ca", ca);
		} catch (Exception e) {
			return Result.failure(e.getMessage());
		}
		
	}
	/**
	 * 删除用户证书
	 * 
	 * @param cert
	 * @return Result
	 */
	@PostMapping("/deletCert")
	public Result deletCert(String id) {
		try {
			boolean deleteById = userCertService.deleteById(id);
			if (deleteById) {
				return Result.success();
			}
			return Result.failure("删除证书数据失败");
		} catch (Exception e) {
			return Result.failure(e.getMessage());
		}

	}
	
	private Map<String, Object> toCert(byte[] certs) {
		try {
			ByteArrayInputStream bio = new ByteArrayInputStream(certs);
			CertificateFactory cf = CertificateFactory.getInstance("X.509");
			X509Certificate certificate = (X509Certificate) cf.generateCertificate(bio);
			BigInteger serialNumber = certificate.getSerialNumber();
			String issuer = certificate.getIssuerDN().getName();
			String subject = certificate.getSubjectDN().getName();
			Map<String, Object> result = new HashMap<>();
			result.put("serialNumber",  serialNumber.toString(16));
			result.put("issuer", issuer);
			result.put("subject", subject);
			return result;
		} catch (Exception e) {
			return null;
		}
	
	}
}
